// SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
// SPDX-License-Identifier: Mulan PSL v2
package storage

import (
	"math"

	"gorm.io/gorm"

	"code.geniusai.org/notebook-manager/pkg/entity"
)

type PvcStoreInterface interface {
	CreatePvc(db *gorm.DB, pvc *entity.Pvc) (*entity.Pvc, error)
	GetPvc(id string) (*entity.Pvc, error)
	GetUserPvcByName(name string, userId string) (*entity.Pvc, error)
	DeletePvc(id string) error
	DeletePvcRecords(db *gorm.DB, userId string) error
	ListPvc(opts *entity.UserListOption) (int, []*entity.Pvc, error)
}

type PvcStore struct {
	db *gorm.DB
}

func NewPvcStore(db *gorm.DB) PvcStoreInterface {
	return &PvcStore{db}
}

func (m *PvcStore) CreatePvc(db *gorm.DB, pvc *entity.Pvc) (*entity.Pvc, error) {
	result := db.Create(pvc)
	return pvc, result.Error
}

func (m *PvcStore) GetPvc(id string) (*entity.Pvc, error) {
	pvc := &entity.Pvc{ID: id}
	result := m.db.First(pvc)
	return pvc, result.Error
}

func (m *PvcStore) GetUserPvcByName(name string, userId string) (*entity.Pvc, error) {
	pvc := &entity.Pvc{Name: name, UserID: userId}
	result := m.db.Where("name = ? and user_id = ?", name, userId).First(&pvc)
	return pvc, result.Error
}

func (m *PvcStore) DeletePvc(id string) error {
	return m.db.Delete(&entity.Pvc{}, id).Error
}

func (m *PvcStore) DeletePvcRecords(db *gorm.DB, userId string) error {
	return db.Where("user_id = ?", userId).
		Delete(&entity.Pvc{}).Error
}

func (m *PvcStore) ListPvc(option *entity.UserListOption) (int, []*entity.Pvc, error) {
	// 过滤关键字, 排序, 分页
	if option.PageSize == 0 {
		option.PageNum = 0
		option.PageSize = math.MaxInt8
	}
	keyword, err := ProcessKeyword(option.Keyword)
	if err != nil {
		return 0, nil, err
	}

	var total int
	pageList := make([]*entity.Pvc, 0)
	err = m.db.Transaction(func(tx *gorm.DB) error {
		query := tx.Model(entity.Pvc{}).
			Where("user_id = ?", option.UserID)
		if option.Keyword != "" {
			query = query.Where("name like ?", keyword)
		}
		var total64 int64
		qErr := query.Count(&total64).Error
		if qErr != nil {
			return qErr
		}
		total = int(total64)
		start := option.PageSize * option.PageNum
		if start < total {
			end := option.PageSize*option.PageNum + option.PageSize
			limit := option.PageSize
			if end >= total {
				limit = end - start
			}
			qErr := query.Order("update_time desc").
				Offset(start).
				Limit(limit).
				Find(&pageList).
				Error
			if qErr != nil {
				return qErr
			}
		}
		return nil
	})
	if err != nil {
		return 0, nil, err
	}

	return total, pageList, nil
}
